package info.davidesposito.bamboomonitor.display;

import info.davidesposito.arduino.communication.SerialCommunication;
import info.davidesposito.arduino.communication.StandardSerialCommunication;
import info.davidesposito.bamboomonitor.display.DisplayModule.DisplayStatus;
import info.davidesposito.bamboomonitor.loops.BambooLoop;
import info.davidesposito.bamboomonitor.loops.BambooLoopModule;

import java.util.List;

public class StandardBambooDisplay extends BambooDisplay {
	
	public final static int DISPLAY_UPDATE_DELAY = 5000;
	public final static int LOOP_STATUS_FAILED = 0;
	public final static int LOOP_STATUS_PASSED = 1 << 5;
	public final static int BUILD_STATUS_QUEUED = 0;
	public final static int BUILD_STATUS_WAITING = 1 << 6;
	public final static int BUILD_STATUS_BUILDING = 2 << 6;
	
	private DisplayStatus displayStatus;
	private SerialCommunication arduinoSerialComm;
	private List<BambooLoop> loops = BambooLoopModule.CORE_COMMUNITY_LOOPS;
	
	public StandardBambooDisplay() {
		super();
		displayStatus = DisplayStatus.DISCONNECTED;
	}
	
	public synchronized void killDisplay() {
		displayStatus = DisplayStatus.DISCONNECTED;
	}
	
	@Override
	public DisplayStatus connect() {
		try {
			arduinoSerialComm = new StandardSerialCommunication("", 9600);
			displayStatus = DisplayStatus.CONNECTED;
		} catch (Exception e) {
			displayStatus = DisplayStatus.ERROR;
		}
		return displayStatus;
	}
	
	@Override
	public void run() {
		if (displayStatus != DisplayStatus.CONNECTED) {
			connect();
		}
		while (displayStatus == DisplayStatus.CONNECTED) {
			for (int i=0;i<loops.size();i++) {
				BambooLoop loop = loops.get(i);
				int status = i;
				switch (loop.getBuildStatus()) {
					case BUILDING:
						status |= BUILD_STATUS_BUILDING;
						break;
					case WAITING:
						status |= BUILD_STATUS_WAITING;
						break;
					case QUEUED:
						status |= BUILD_STATUS_QUEUED;
				}
				switch (loop.getLoopStatus()) {
					case PASSING:
						status |= LOOP_STATUS_PASSED;
						break;
					case FAILING:
						status |= LOOP_STATUS_FAILED;
				}
				arduinoSerialComm.write(new byte[] {(byte)status});
			}
		}
	}

	@Override
	public void update() {
		// this might (most likely will) cause an exception
		this.notify();
	}

	@Override
	public DisplayStatus getDisplayStatus() {
		return displayStatus;
	}

}
